defmodule ShareGroup.User do
    use Ecto.Schema
    require Ecto.Query
    require Logger

    schema "user" do
        field :telephone, :string
        field :mail, :string
        field :username, :string, null: false
        field :password, :string, null: false
        field :timetable, :string

        timestamps()
    end

    def changeset(user, params \\ %{}) do
        user
            |> Ecto.Changeset.cast(params, [:telephone, :mail, :username, :password, :timetable])
            |> Ecto.Changeset.validate_required([:telephone, :mail, :username, :password])
            |> Ecto.Changeset.validate_format(:telephone, ~r/^[1][358][0-9]{9}$/ ,message: "invalid telephone number")
            |> Ecto.Changeset.validate_format(:mail, ~r/@qq.com$|@163.com$|@gmail.com$/, message: "invalid email address(only support qq 163 gmail )")
            |> Ecto.Changeset.unique_constraint(:telephone, name: :user_telephone_mail_index)
            |> Ecto.Changeset.unique_constraint(:mail, name: :user_telephone_mail_index)
    end
            # |> Ecto.Changeset.validate_format(:password, ~r/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$/, message: "invalid password number , must have both alpha & digit legth 8- 16")
            # 不好处理对于密码格式的改变，估计能够通过put_change来实现，当前先不考虑


    @doc """
    提取Ecto.Changeset中的报错信息
    """
    def getErrorMsg([], map) do
        map
    end

    def getErrorMsg(msg, map \\ %{}) do
        [{key, value} | next ] = msg
        getErrorMsg(next, Map.put(map, key, elem(value, 0)))
    end

    @doc """
    根据key查询对应的账户
    """
    def findUser(user, getbykey) do

        case getbykey do

            :telephone -> 

                ShareGroup.User 
                |> Ecto.Query.where(telephone: ^user.telephone)
                |> ShareGroup.Repo.one

            :mail ->

                ShareGroup.User 
                |> Ecto.Query.where(mail: ^user.mail)
                |> ShareGroup.Repo.one

            :username ->

                ShareGroup.User 
                |> Ecto.Query.where(username: ^user.username)
                |> ShareGroup.Repo.all

            _ ->
                nil
        end
    end

    def shownamelist(userlist) do
        list = ShareGroup.User |> ShareGroup.Repo.all

        namelist = Enum.filter_map(list, fn member -> member.id in userlist end,
                                    fn member ->
                                        %{id: member.id, username: member.username}
                                    end)
       %{namelist: namelist}                    
    end

    @doc """
    对密码进行哈希处理
    """
    def generateHash(key, str) when is_bitstring(key <> str) do
        Base.encode16(:crypto.hash(:sha256, key <> str))
    end

    def confirmUser(nil, _) do
        nil
    end

    def confirmUser([], _) do
        nil
    end

    @doc """
    判断用户是否输入正确的密码
    """
    def confirmUser(user, pwd) do
        # IO.inspect user
        key = generateHash(user.telephone, pwd)
        Logger.info "#{IO.inspect user.telephone} #{ IO.inspect pwd} generate password : #{key}"

        case user.password == key do
            true -> user
            false -> nil
        end
    end

    @doc """
    根据输入的账户名，判断是手机号登陆还是邮箱登陆
    """
    def detectUserType(usrname) do

        telephtoneFormat = ~r/^[1][358][0-9]{9}$/
        mailFormat = ~r/@qq.com$|@163.com$|@gmail.com$/

         cond do
            usrname =~ telephtoneFormat -> :telephone
            usrname =~ mailFormat -> :mail
            true -> nil
        end
    end


end